﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SAP.Middleware.Connector;
using CM.DL.DALC.NC03;
using DECOR.BL.BE;

namespace DECOR.DL.DALC.NC03
{
    public class ClienteDALC : IClienteDALC
    {
        private string _connId = string.Empty;

        public static ClienteDALC Instance(string pConnId)
        {
            if (_instance == null)
            {
                lock (typeof(ClienteDALC))
                {
                    if (_instance == null)
                    {
                        _instance = new ClienteDALC(pConnId);
                    }
                }
            }
            return _instance;
        }
        private ClienteDALC(string pConnId) { this._connId = pConnId; }
        private ClienteDALC() { }
        private static volatile ClienteDALC _instance = null;   

        #region IClienteDALC Members

        //No usar para NCO3 se modifico.
        /// <summary>
        /// Devuelve una lista de clientes segun el parametro.
        /// </summary>
        /// <param name="pNombre">Nombre o parte del nombre de un cliente.</param>
        /// <returns>Devuelve lista de clientes</returns> 
        public List<DECOR.BL.BE.ClienteBE> buscar(string pNombre)
        {
            IRfcFunction function = null;
            RfcDestination dest = null;
            List<ClienteBE> listaResult = new List<ClienteBE>();
            ClienteBE obj = null;
            DestConfig dc = new DestConfig();
            try
            {
                dest = DALC.getDestination(out dc);
                function = dest.Repository.CreateFunction("ZWEB_BUSCA_CLIENTES");
                function.SetValue("IM_NAME", pNombre);
                function.Invoke(dest);

                IRfcTable TCLIENTES = function.GetTable("TABLA_CLIENTES");
                string RESULT = function.GetString("EX_RESULT");

                foreach (IRfcStructure item in TCLIENTES)
                {
                    obj = new ClienteBE();

                    obj.Codigo = item["KUNNR"].GetString();
                    obj.Descripcion = item["NAME1"].GetString().Trim() + (item["NAME2"].GetString().Trim().Equals("") ? "" : " " + item["NAME2"].GetString());
                    obj.Ruc = item["STCD1"].GetString();
                    listaResult.Add(obj);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                //RfcDestinationManager.UnregisterDestinationConfiguration(dc);
            }
            return listaResult;
        }

        /// <summary>
        /// retorna la información del cliente
        /// </summary>
        /// <param name="pCodigo">Código del cliente</param>
        /// <returns>Devuelve los datos del cliente</returns>
        public DECOR.BL.BE.ClienteBE leer(string pCodigo)
        {
            IRfcFunction function = null;
            RfcDestination dest = null;
            ClienteBE obj = null;
            DestConfig dc = new DestConfig();
            try
            {
                dest = DALC.getDestination(out dc);
                function = dest.Repository.CreateFunction("ZWEB_LEE_CLIENTE");
                function.SetValue("IM_KUNNR", pCodigo);
                function.Invoke(dest);

                IRfcTable INTER = function.GetTable("T_INTER");
                string RESULT = function.GetString("EX_RESULT");
                string CLIEVE = function.GetString("EX_CLIEVE");

                foreach (IRfcStructure item in INTER)
                {
                    obj = new ClienteBE();

                    obj.Codigo = item["KUNNR"].GetString();
                    obj.Ruc = item["STCD1"].GetString();
                    obj.Descripcion = item["NOMBRE"].GetString();
                    obj.Ciudad = item["CITY"].GetString();
                    obj.Direccion = item["STREET"].GetString();
                    obj.CodigoPostal = item["POSTL_CODE"].GetString();
                    obj.Telefono = item["TELEPHONE"].GetString();
                    obj.Mail = item["E_MAIL"].GetString();

                    obj.Eventual = CLIEVE == "X" ? true : false;
                    break;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                //RfcDestinationManager.UnregisterDestinationConfiguration(dc);
            }
            return obj;
        }

        /// <summary>
        /// devuelve la lista de organizaciones de venta
        /// </summary>
        /// <param name="pCodCliente">Código del cliente</param>
        /// <returns>Lista de organizaciones de venta</returns>
        public List<DECOR.BL.BE.GenericBE> listaOrgVtas(string pCodCliente)
        {
            IRfcFunction function = null; RfcDestination dest = null;
            DestConfig dc = new DestConfig();
            List<GenericBE> lstOrgVtas = new List<GenericBE>();
            GenericBE obj = null;
            try
            {
                dest = DALC.getDestination(out dc);
                function = dest.Repository.CreateFunction("ZWEB_LISTA_ORGVTAS");
                function.SetValue("IM_KUNNR", pCodCliente);
                function.Invoke(dest);

                IRfcTable TVKOT = function.GetTable("T_TVKOT");

                foreach (IRfcStructure item in TVKOT)
                {
                    obj = new GenericBE();

                    obj.Codigo = item["VKORG"].GetString();
                    obj.Descripcion = item["VKORG"].GetString() + " :: " + item["VTEXT"].GetString();
                    lstOrgVtas.Add(obj);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                //RfcDestinationManager.UnregisterDestinationConfiguration(dc);
            }
            return lstOrgVtas;
        }

        public List<DECOR.BL.BE.GenericBE> listaCanalDist(string pCodCliente, string pCodOrgVtas)
        {
            IRfcFunction function = null;
            RfcDestination dest = null;
            List<GenericBE> lstCanalesDist = new List<GenericBE>();
            GenericBE obj = null;
            DestConfig dc = new DestConfig();
            try
            {
                dest = DALC.getDestination(out dc);
                function = dest.Repository.CreateFunction("ZWEB_LISTA_CANALDIST");
                function.SetValue("IM_KUNNR", pCodCliente);
                function.SetValue("IM_VKORG", pCodOrgVtas);
                function.Invoke(dest);

                IRfcTable T_TVTWT = function.GetTable("T_TVTWT");

                foreach (IRfcStructure item in T_TVTWT)
                {
                    obj = new GenericBE();

                    obj.Codigo = item["VTWEG"].GetString();
                    obj.Descripcion = item["VTWEG"].GetString() + " :: " + item["VTEXT"].GetString();
                    lstCanalesDist.Add(obj);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                //RfcDestinationManager.UnregisterDestinationConfiguration(dc);
            }
            return lstCanalesDist;
        }

        public List<DECOR.BL.BE.GenericBE> listaSectores()
        {
            throw new NotImplementedException();
        }

        public DECOR.BL.BE.PersonaBE buscaVendedor(string pCodCliente, string pCodOrgVtas, string pCodCanalDist)
        {
            IRfcFunction function = null;
            RfcDestination dest = null;
            PersonaBE obj = null;
            DestConfig dc = new DestConfig();
            try
            {
                dest = DALC.getDestination(out dc);
                function = dest.Repository.CreateFunction("ZWEB_BUSCA_VENDEDOR");
                function.SetValue("IM_KUNNR", pCodCliente);
                function.SetValue("IM_VKORG", pCodOrgVtas);
                function.SetValue("IM_VTWEG", pCodCanalDist);
                function.Invoke(dest);

                IRfcTable PA0002 = function.GetTable("T_PA0002");

                foreach (IRfcStructure item in PA0002)
                {
                    obj = new PersonaBE();
                    obj.CodPersona = item["PERNR"].GetString();
                    obj.Nombre = item["VORNA"].GetString();
                    obj.Apellido = item["NACHN"].GetString();
                    obj.ApeSoltero = item["NAME2"].GetString();
                    obj.Iniciales = item["INITS"].GetString();
                    obj.Descripcion = (item["VORNA"].GetString() + " " + item["NACHN"].GetString() + " " + item["NAME2"].GetString()).Trim();
                    break;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                //RfcDestinationManager.UnregisterDestinationConfiguration(dc);
            }

            return obj;
        }

        /// <summary>
        /// Busca Condicion Pago y Expedicion
        /// </summary>
        /// <param name="pCodCliente">Código de cliente.</param>
        /// <param name="pCodOrgVtas">Código de Organización de ventas.</param>
        /// <param name="pCodCanalDist">Código de Canal de distribución.</param>
        /// <param name="pCodSector">Código de sector.</param>
        /// <param name="pCondPago">Valor de retorno: Clave de condiciones de pago.</param>
        /// <param name="pCondExp">Valor de retorno: Condición de expedición.</param>  
        public void infoClienteNac(string pCodCliente, string pCodOrgVtas, string pCodCanalDist, string pCodSector, out string pCondPago, out string pCondExp)
        {
            IRfcFunction function = null;
            RfcDestination dest = null;
            List<GenericBE> lstCanalesDist = new List<GenericBE>();
            GenericBE obj = null;
            pCondExp = ""; pCondPago = "";
            DestConfig dc = new DestConfig();
            try
            {
                dest = DALC.getDestination(out dc);
                function = dest.Repository.CreateFunction("ZWEB_BUSCA_CONDICIONES");
                function.SetValue("IM_KUNNR", pCodCliente);
                function.SetValue("IM_VKORG", pCodOrgVtas);
                function.SetValue("IM_VTWEG", pCodCanalDist);
                function.SetValue("IM_SPART", pCodSector);
                function.Invoke(dest);

                pCondExp = function.GetString("EX_VSBED");
                pCondPago = function.GetString("EX_ZTERM");
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                //RfcDestinationManager.UnregisterDestinationConfiguration(dc);
            }
        }

        public string validaInterlocutor(ref DECOR.BL.BE.ClienteBE pClienteBE, string pCodOrgVtas, string pCodCanalDist, string pCodSector)
        {
            throw new NotImplementedException();
        }

        public string validaRUC(string pRuc, string pOrgVtas)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IClienteDALC Members

        /// <summary>
        /// Devuelve una lista de clientes segun los parámetros.
        /// </summary>
        /// <param name="pNombre">Nombre o parte del nombre de un cliente.</param>
        /// <param name="pIdentifFiscal">Número de identificación fiscal.</param>
        /// <param name="pNumeroDeudor">Número de deudor.</param>
        /// <returns>Devuelve lista de clientes</returns> 
        public List<ClienteBE> busquedaCliente(string pNombre, string pIdentifFiscal, string pNumeroDeudor)
        {
            IRfcFunction function = null;
            RfcDestination dest = null;
            List<ClienteBE> listaResult = new List<ClienteBE>();
            ClienteBE obj = null;
            DestConfig dc = new DestConfig();
            try
            {
                dest = DALC.getDestination(out dc);
                function = dest.Repository.CreateFunction("ZCM_SD_006");
                function.SetValue("IM_NAME", pNombre);
                function.SetValue("IM_STCD1", pIdentifFiscal);
                function.SetValue("IM_KUNNR", pNumeroDeudor);
                function.Invoke(dest);

                IRfcTable TCLIENTES = function.GetTable("T_CLIENTES");
                string RESULT = function.GetString("EX_RESULT");

                foreach (IRfcStructure item in TCLIENTES)
                {
                    obj = new ClienteBE();

                    obj.Codigo = item["KUNNR"].GetString();
                    obj.Descripcion = item["NOMBRE"].GetString().Trim(); // +(item["NAME2"].GetString().Trim().Equals("") ? "" : " " + item["NAME2"].GetString());
                    obj.Ruc = item["STCD1"].GetString();
                    listaResult.Add(obj);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                //RfcDestinationManager.UnregisterDestinationConfiguration(dc);
            }
            return listaResult;
        }

        /// <summary>
        /// Búsqueda de clientes en la tabla Reniec (ZTSD_CLIENTES)
        /// </summary>
        /// <param name="pNumDoc">Número de documento del cliente.</param>
        /// <param name="pResult">Si es 00 indica que existe datos, caso contrario no se encontró el cliente.</param>
        /// <returns></returns>
        public ClienteBE busquedaClienteReniec(string pNumDoc, string pNombre, string pApePat, string pApeMat, out string retval)
        {
            IRfcFunction function = null;
            RfcDestination dest = null;
            ClienteBE cliResult = new ClienteBE();
            DestConfig dc = new DestConfig();
            retval = "";
            try
            {
                dest = DALC.getDestination(out dc);
                function = dest.Repository.CreateFunction("ZWEB_LEE_DNI");
                function.SetValue("P_DNI", pNumDoc);

                function.Invoke(dest);

                IRfcTable TCLIENTES = function.GetTable("T_DATA");
                foreach (IRfcStructure item in TCLIENTES)
                {
                    cliResult = new ClienteBE();
                    cliResult.CODIG = item["CODIG"].GetString();
                    cliResult.APPAT = item["APPAT"].GetString();
                    cliResult.APMAT = item["APMAT"].GetString();
                    cliResult.NOMBRE = item["NOMBRE"].GetString();
                    cliResult.DIREC = item["DIREC"].GetString();
                    cliResult.ZCODE = item["ZCODE"].GetString();
                    cliResult.Ciudad = item["UBIGEO"].GetString();
                    if (item["FECNAC"].GetString() != "0000-00-00")
                    {
                        cliResult.FECNAC = Convert.ToDateTime(item["FECNAC"].GetString());
                        //calculando la edad
                        TimeSpan a = DateTime.Today.Subtract(cliResult.FECNAC);
                        double edad = a.Days / 365;
                        cliResult.EDAD = edad.ToString();
                    }
                    else
                    {
                        cliResult.FECNAC = DateTime.Now;
                        cliResult.EDAD = "0";
                    }
                    cliResult.SEXO = item["SEXO"].GetString();
                    cliResult.GRAINS = item["GRAINS"].GetString();
                }
                cliResult.NIVELSE = function.GetString("P_NIVELSE");
            }
            catch (RfcCommunicationException ex)
            {
                retval = "Confirme nuevamente la operación por favor.";
                //throw ex;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                //RfcDestinationManager.UnregisterDestinationConfiguration(dc);
            }
            return cliResult;
        }

        public void insertClienteReniec(ClienteBE objCliente, out string result)
        {
            IRfcFunction function = null; RfcDestination dest = null;
            DestConfig dc = new DestConfig();
            try
            {
                dest = DALC.getDestination(out dc);
                RfcStructureMetadata sm = dest.Repository.GetStructureMetadata("ZTSD_CLIENTES");
                IRfcStructure sCliente = sm.CreateStructure();

                sCliente.SetValue("CODIG", objCliente.CODIG);
                sCliente.SetValue("APPAT", objCliente.APPAT);
                sCliente.SetValue("APMAT", objCliente.APMAT);
                sCliente.SetValue("NOMBRE", objCliente.NOMBRE);
                sCliente.SetValue("DIREC", objCliente.DIREC);
                sCliente.SetValue("ZCODE", objCliente.ZCODE);
                //sCliente.SetValue("CIUDAD", objCliente.Ciudad);
                sCliente.SetValue("FECNAC", objCliente.FECNAC);
                sCliente.SetValue("SEXO", objCliente.SEXO);
                sCliente.SetValue("UBIGEO", objCliente.Ciudad);
                sCliente.SetValue("GRAINS", objCliente.GRAINS);
                //sCliente.SetValue("EDAD", objCliente.EDAD);

                function = dest.Repository.CreateFunction("ZCM_SD_010");
                function.SetValue("P_CLIENTE", sCliente);
                function.Invoke(dest);
                result = function.GetString("E_RESULT");
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally {
                //RfcDestinationManager.UnregisterDestinationConfiguration(dc);
            }
        }
        #endregion

        public List<GenericBE> ListarGradoInstruccion()
        {
            IRfcFunction function = null;
            RfcDestination dest = null;
            List<GenericBE> listaResult = new List<GenericBE>();
            GenericBE obj = null;
            DestConfig dc = new DestConfig();
            try
            {
                dest = DALC.getDestination(out dc);
                function = dest.Repository.CreateFunction("ZWEB_LISTA_GRADOINSTRUCCION");
                function.Invoke(dest);

                IRfcTable TGRADOINST = function.GetTable("T_GRAINSTRU");

                foreach (IRfcStructure item in TGRADOINST)
                {
                    obj = new GenericBE();

                    obj.Codigo = item["CODGI"].GetString();
                    obj.Descripcion = item["DESCR"].GetString();
                    listaResult.Add(obj);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                //RfcDestinationManager.UnregisterDestinationConfiguration(dc);
            }
            return listaResult;
        }

        public List<ClientePreResBE> ListaPreguntas()
        {
            IRfcFunction function = null;
            RfcDestination dest = null;
            List<ClientePreResBE> listaResult = new List<ClientePreResBE>();
            ClientePreResBE obj = null;
            ClientePreResBE objR = null;
            GenericBE objG = null;
            List<ClientePreResBE> listaFinal = new List<ClientePreResBE>();
            DestConfig dc = new DestConfig();
            try
            {
                dest = DALC.getDestination(out dc);
                function = dest.Repository.CreateFunction("ZWEB_LISTA_PRE_REP");
                function.Invoke(dest);

                IRfcTable T_LISTA = function.GetTable("T_LISTA");

                foreach (IRfcStructure item in T_LISTA)
                {
                    obj = new ClientePreResBE();
                    obj.codPre = item["CODPRE"].GetString();
                    obj.txtPre = item["TXTPRE"].GetString();
                    listaResult.Add(obj);
                }

                var gr = listaResult.GroupBy(x => new { x.codPre, x.txtPre });

                foreach (var itm in gr){
                    objR = new ClientePreResBE();
                    objR.codPre = itm.Key.codPre;
                    objR.txtPre = itm.Key.txtPre;
                    objR.listaResp = new List<GenericBE>();
                    foreach (IRfcStructure item in T_LISTA)
                    {
                        if (item["CODPRE"].GetString() == itm.Key.codPre)
                        {
                            objG = new GenericBE();
                            objG.Codigo = item["CODREP"].GetString();
                            objG.Descripcion = item["TXTREP"].GetString();
                            objR.listaResp.Add(objG);
                        }
                    }
                    listaFinal.Add(objR);
                }

            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                //RfcDestinationManager.UnregisterDestinationConfiguration(dc);
            }
            return listaFinal;
        }

        public void insertClientePregRep(List<ClienteBE> listCliente)
        {
            if (listCliente != null && listCliente.Count > 0)
            {
                IRfcFunction function = null; RfcDestination dest = null;
                DestConfig dc = new DestConfig();
                try
                {
                    dest = DALC.getDestination(out dc);
                    RfcStructureMetadata sm = dest.Repository.GetStructureMetadata("ZTSD_TABFIDCLI");
                    IRfcTable tCliente = sm.CreateTable();
                    IRfcStructure sCliente = sm.CreateStructure();

                    foreach (ClienteBE item in listCliente)
                    {
                        sCliente = sm.CreateStructure();
                        sCliente.SetValue("DNI", item.CODIG);
                        sCliente.SetValue("CODP", item.CODP);
                        sCliente.SetValue("CODR", item.CODR);

                        tCliente.Append(sCliente);
                    }
                    function = dest.Repository.CreateFunction("ZWEB_GRABAR_PREGREP");
                    function.SetValue("P_PREGREP", tCliente);
                    function.Invoke(dest);
                }
                catch (Exception)
                {

                    throw;
                }
                finally {
                    //RfcDestinationManager.UnregisterDestinationConfiguration(dc);
                }
            }
        }

        public List<ClienteBE> busquedaClientePregRep(string numDoc)
        {
            IRfcFunction function = null;
            RfcDestination dest = null;
            List<ClienteBE> listaResult = new List<ClienteBE>();
            ClienteBE obj = null;
            DestConfig dc = new DestConfig();
            try
            {
                dest = DALC.getDestination(out dc);
                function = dest.Repository.CreateFunction("ZWEB_BUSCAR_PREGRES_CLI");
                function.SetValue("P_DNI", numDoc);
                function.Invoke(dest);

                IRfcTable TBUSQUEDA = function.GetTable("T_BUSQUEDA");

                foreach (IRfcStructure item in TBUSQUEDA)
                {
                    obj = new ClienteBE();

                    obj.CODIG = item["DNI"].GetString();
                    obj.CODP = item["CODP"].GetString();
                    obj.CODR = item["CODR"].GetString();

                    listaResult.Add(obj);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                //RfcDestinationManager.UnregisterDestinationConfiguration(dc);
            }
            return listaResult;
        }

        
    }
}
